/*
 * jyd-31.c
 *
 *  Created on: 2025锟斤拷9锟斤拷27锟斤拷
 *      Author: Move
 */

#include "zf_common_headfile.h"

static  fifo_struct     bluetooth_jyd31_fifo;                                  // FIFO 环形缓冲区结构体定义
static  uint8           bluetooth_jyd31_buffer[BLUETOOTH_JYD31_BUFFER_SIZE];  // 数据存储缓冲区

static  uint8           bluetooth_jyd31_data = 0;                              // 串口接收数据临时变量

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 发送单字节
// 参数说明     data            8bit 数据
// 返回参数     uint32          剩余未发送长度
// 使用示例     bluetooth_jyd31_send_byte(0x5A);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_send_byte (const uint8 data)
{
    uart_write_byte(BLUETOOTH_JYD31_INDEX, data);                              // 直接发送数据，等待发送完成
    return 1;                                                                   // 发送成功
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 发送缓冲区
// 参数说明     buff             需要发送的数据地址
// 参数说明     len              发送长度
// 返回参数     uint32           剩余未发送的字节数
// 使用示例     bluetooth_jyd31_send_buffer(buff, 16);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_send_buffer (const uint8 *buff, uint32 len)
{
    zf_assert(NULL != buff);
    uart_write_buffer(BLUETOOTH_JYD31_INDEX, buff, len);                       // 直接发送数据，等待发送完成
    return 0;                                                                   // 返回0表示全部发送成功
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 发送字符串
// 参数说明     *str            要发送的字符串地址
// 返回参数     uint32          剩余发送长度
// 使用示例     bluetooth_jyd31_send_string("Trust yourself.");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_send_string (const char *str)
{
    zf_assert(NULL != str);
    uint32 len = strlen(str);
    uart_write_buffer(BLUETOOTH_JYD31_INDEX, (const uint8 *)str, len);            // 直接发送字符串到串口
    return 0;                                                                      // 返回0表示全部发送成功
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 发送摄像头图像数据 单位可以看图像
// 参数说明     *image_addr     要发送的图像地址
// 参数说明     image_size      图像大小
// 返回参数     void
// 使用示例     bluetooth_jyd31_send_image(&mt9v03x_image[0][0], MT9V03X_IMAGE_SIZE);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_jyd31_send_image (const uint8 *image_addr, uint32 image_size)
{
    zf_assert(NULL != image_addr);

    bluetooth_jyd31_send_buffer(camera_send_image_frame_header, 4);
    bluetooth_jyd31_send_buffer((uint8 *)image_addr, image_size);
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 读取数据
// 参数说明     buff            存储数据的地址
// 参数说明     len             长度
// 返回参数     uint32          实际读取字节数
// 使用示例     bluetooth_jyd31_read_buffer(buff, 16);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_read_buffer (uint8 *buff, uint32 len)
{
    zf_assert(NULL != buff);
    uint32 data_len = len;
    fifo_read_buffer(&bluetooth_jyd31_fifo, buff, &data_len, FIFO_READ_AND_CLEAN);
    return data_len;
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 串口中断回调函数
// 参数说明     void
// 返回参数     void
// 使用示例
// 备注信息     该函数在 ISR 文件的串口中断初被调用
//              在串口中断服务函数中会调用 wireless_module_uart_handler() 函数
//              然后 wireless_module_uart_handler() 会回调此函数
//              现在增加了直接在中断中处理紧急停止命令的功能
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_jyd31_uart_callback (void)
{
    uart_query_byte(BLUETOOTH_JYD31_INDEX, &bluetooth_jyd31_data);            // 接收串口数据
    fifo_write_buffer(&bluetooth_jyd31_fifo, &bluetooth_jyd31_data, 1);       // 写入 FIFO
    
    // 在中断中直接处理紧急停止命令（实时响应）
    bluetooth_emergency_stop_handler_isr(bluetooth_jyd31_data);
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙转串口模块 初始化
// 参数说明     void
// 返回参数     uint8           初始化状态 0-成功 1-失败
// 使用示例     bluetooth_jyd31_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 bluetooth_jyd31_init (void)
{
    uint8 return_state = 0;
    set_wireless_type(BLUETOOTH_CH9141, bluetooth_jyd31_uart_callback);  // 设置CH9141类型

    fifo_init(&bluetooth_jyd31_fifo, FIFO_DATA_8BIT, bluetooth_jyd31_buffer, BLUETOOTH_JYD31_BUFFER_SIZE);
    // 注意：这里使用的串口波特率为9600 为JYD-31蓝牙模块的出厂波特率
    // JYD-31只有4个引脚，无RTS等流控引脚，直接初始化UART
    uart_init(BLUETOOTH_JYD31_INDEX, BLUETOOTH_JYD31_BUAD_RATE, BLUETOOTH_JYD31_RX_PIN, BLUETOOTH_JYD31_TX_PIN);
    uart_rx_interrupt(BLUETOOTH_JYD31_INDEX, 1);

    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
// 函数名     蓝牙转串口模块 发送无符号整数
// 函数说明     value           要发送的数值
// 函数说明     width           显示宽度（不足时前面补0）
// 返回参数     uint32         剩余未发送长度
// 使用示例     bluetooth_jyd31_send_uint(123, 5);
// 注意事项
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_send_uint (uint32 value, uint8 width)
{
    char num_str[12];
    sprintf(num_str, "%0*lu", width, value);                                      // 格式化为指定宽度的字符串
    uart_write_buffer(BLUETOOTH_JYD31_INDEX, (const uint8 *)num_str, strlen(num_str));
    return 0;                                                                      // 返回0表示全部发送成功
}

//-------------------------------------------------------------------------------------------------------------------
// 函数名     蓝牙转串口模块 发送有符号整数
// 函数说明     value           要发送的数值
// 函数说明     width           显示宽度（不足时前面补0）
// 返回参数     uint32         剩余未发送长度
// 使用示例     bluetooth_jyd31_send_int(-123, 5);
// 注意事项
//-------------------------------------------------------------------------------------------------------------------
uint32 bluetooth_jyd31_send_int (int32 value, uint8 width)
{
    char num_str[12];
    sprintf(num_str, "%0*d", width, (int)value);                                  // 格式化为指定宽度的有符号字符串
    uart_write_buffer(BLUETOOTH_JYD31_INDEX, (const uint8 *)num_str, strlen(num_str));
    return 0;                                                                      // 返回0表示全部发送成功
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙紧急停止控制处理（中断版本 - 实时响应）
// 参数说明     data            接收到的单字节数据
// 返回参数     void
// 使用示例     在蓝牙UART中断回调中调用: bluetooth_emergency_stop_handler_isr(receive_data);
// 备注信息     命令格式：
//              发送 'S' 或 '1' - 设置紧急停止 (emergency_stop_flag = 1)
//              发送 'R' 或 '0' - 恢复运行 (emergency_stop_flag = 0)
//              发送 'Q' - 查询当前状态
//              在中断中处理，响应速度更快
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_emergency_stop_handler_isr (uint8 data)
{
    // 声明为外部变量，需要在Menu.h中声明
    extern uint8 emergency_stop_flag;

    switch(data)
    {
        case 'S':   // Stop - 紧急停止
        case 's':
        case '1':
            Motor_Open = 0;   Servo_Open = 0;
            bluetooth_jyd31_send_string("stop\r\n");
            break;

        case 'R':   // Run - 恢复运行
        case 'r':
        case '0':
            Motor_Open = 1;   Servo_Open = 1;
            bluetooth_jyd31_send_string("gogogo:\r\n");
            break;

        default:
            // 未知命令，不做处理
            break;
    }
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     蓝牙紧急停止控制处理（主循环版本 - 兼容保留）
// 参数说明     void
// 返回参数     void
// 使用示例     在主循环中周期性调用: bluetooth_emergency_stop_handler();
// 备注信息     如果使用中断版本处理，此函数可以不调用
//              保留此函数是为了兼容性和灵活性
//-------------------------------------------------------------------------------------------------------------------
void bluetooth_emergency_stop_handler (void)
{
    uint8 receive_data;
    uint32 data_len = 1;
    
    // 从FIFO中读取数据
    if(fifo_read_buffer(&bluetooth_jyd31_fifo, &receive_data, &data_len, FIFO_READ_AND_CLEAN))
    {
        bluetooth_emergency_stop_handler_isr(receive_data);
    }
}

